/* GameInfoProvider.java
 * 
 * Alfred Olschnoegger
 * 24.05.2008
 */

package application;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import application.parser.Parser;
import application.parser.StringParser;
import application.valueObjects.GameObjectValue;
import application.valueObjects.GameValue;
import application.valueObjects.HunterValue;
import domain.GameObject;
import domain.Hunter;
import domain.game.Game;
import domain.game.GameManager;
import domain.location.GameArea;
import domain.location.Position;
import exceptions.GameEndedException;
import exceptions.GameNotExistingException;
import exceptions.ObjectNotFoundException;

/**
 * This class manages the game information.
 *
 * @date 24.05.2008
 * @author Alfred Olschnoegger
 */

public class GameInfoProvider {
	Game m_Game;
	
	/**
	 * Constructor which reads the Game for the game info provider
	 * 
	 * @param gameID searched gameID
	 * @throws GameNotExistingException 
	 */
	public GameInfoProvider(int gameID) throws GameNotExistingException {
		m_Game = GameManager.getInstance().getGame(gameID);
		if (m_Game == null)
			throw new GameNotExistingException();
	}
	
	
	public GameInfoProvider() {
	}

	/**
	 * 
	 * @return true if the game is set
	 */
	public boolean isValid() {
		if(m_Game == null)
			return false;
		
		return true;
	}

	/**
	 * 
	 * @param hunter hunter which should be added
	 * @return true if the hunter was successfully added.
	 * @throws GameEndedException 
     */
	public boolean addHunter(Hunter hunter) throws GameEndedException {
		return m_Game.addHunter(hunter);
	}

	/**
	 * @return gameID of the managed game
	 */
	public int getGameID() {
		return m_Game.getGameID();
	}

	/**
	 * 
	 * @return true if the game is still running
	 */
	public final boolean isAlive() {
		return m_Game.isAlive();
	}

	/**
	 * 
	 * @param game the managed game
	 */
	public void setGame(Game game) {
		m_Game = game;
	}

	/**
	 * starts the game if it is not allready running
	 * 
	 * @return true if the game was successfully started
	 */
	public boolean start() {
		if(!m_Game.isAlive()) {
			m_Game.start();
			return true;
		}
		return false;
	}

	
	/**
	 * @param hunterName	name of the searched hunter
	 * @return				true if the hunter is already in the container
	 */
	public boolean containsHunter(String hunterName) {
		return m_Game.containsHunter(hunterName);
	}

	/**
	 * 
	 * @param hunterName name of the searched hunter
	 * @return the found hunter
	 */
	public Hunter getHunter(String username) {
		return m_Game.getHunter(username);
	}

	
	/**
	 * uses the given object in the game
	 * 
	 * @param object
	 * @param hunter
	 * @param p_lat
	 * @param p_long
	 * @return
	 */
	public void use(int object, String hunter, int p_X, int p_Y, Parser pars) {
		Hunter hunt = m_Game.getHunter(hunter);
		Position pos = new Position(p_X, p_Y);
		hunt.setPos(pos);
		
		if(m_Game.use(object, hunt)) {
			pars.success();
		} else {
			pars.add(new ObjectNotFoundException());
		}
	}

	public final GameArea getArea() {
		return m_Game.getArea();
	}

	public String getGameName() {
		return m_Game.getGameName();
	}

	public void parse(Parser<String> parse) {
		parse.add(m_Game);
	}


	public void stop() {
		m_Game.end();
	}
	
	public GameValue getGameValue() {
		return new GameValue(m_Game.getGameID(), m_Game.getGameName(), m_Game.getHunterCount(), m_Game.getRemainingTimeslice(), m_Game.getArea().getXMax(), m_Game.getArea().getYMax());
	}
	
	
	public List<HunterValue> getHunterValues() {

		List<HunterValue> list = new LinkedList<HunterValue>();
		List<Hunter> hunters = m_Game.getHunterNames();
		Collections.sort(hunters);
		for (Hunter h : hunters) {
			
			list.add(new HunterValue(h.getName(), h.getKills(), h.getPos().getX(), h.getPos().getY()));
		}
		return list;
	}
	
	public List<HunterValue> getValidHunterValues() {

		List<HunterValue> list = new LinkedList<HunterValue>();
		List<Hunter> hunters = m_Game.getValidHunterNames();
		Collections.sort(hunters);
		for (Hunter h : hunters) {
			list.add(new HunterValue(h.getName(), h.getKills(), h.getPos().getX(),  h.getPos().getY()));
		}

		return list;
	}
	
	public void getHunterValues(Parser parse) {
		List<Hunter> hunters = m_Game.getHunterNames();
		Collections.sort(hunters);
		for (Hunter h : hunters) {
			parse.add(h);
		}
	}
	
	
	public List<GameObjectValue> getObjectValues() {
		List<GameObjectValue> list = new LinkedList<GameObjectValue>();
		for (GameObject o : m_Game.getGameObjects()) {
			//TODO extend if powerup functionality is added
			list.add(new GameObjectValue(GameObjectValue.RABBIT_IDENTIFIER, o.getPos().getX(), o.getPos().getY()));
		}
		
		return list;
	}



	
	
	
}


// end of GameInfoProvider.java
